package com.vsoft.sms_cm;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Logger;

import com.vsoft.framework.core.BaseException;
import com.vsoft.framework.core.BusiObj;
import com.vsoft.framework.core.db.OperAgent;
import com.vsoft.framework.core.db.SQLArgs;
import com.vsoft.framework.core.util.BOHelper;
import com.vsoft.framework.core.util.LogCollect;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import com.vsoft.framework.core.Configuration;



//import .sms_onhook.TestHsqlDB;
public class TableCacheServer {
		
	
	private static Logger vLogger = Logger.getLogger(TableCacheServer.class);
	private static String vName = TableCacheServer.class.getName();
    private static ICacheObj<ArrayList<BusiObj>> vData=null;
    private static ICacheObj<HashMap<String,String>> vWhiteListData=null;
    private static ICacheObj<HashMap<String,String>> vEnterpriseGroupData=null;
    private static ICacheObj<ArrayList<BusiObj>> vTempleGroupData=null;
    private static ICacheObj<ArrayList<BusiObj>> vEnterpriseData=null;
    
    private static ICacheObj<HashMap<String,String>> vConfigListData=null;//红名单，都要发短信，for旺铺
    
    private final static String		RESULT			="RESULT";
	private String vDebugHome = "";
	
	private static int vMode = 2; //1 jvm cache cache  2 redis
	private static String vMaster = "1";
	//add at 20120408 
	private static boolean	flagDebug		=	false;
	Connection vconn	=	null;
	PreparedStatement pst = null;
	ResultSet rs = null;
	//add at 20120428 增加企业集团与企业关系缓存
	private static String genSqlEnterpriseGroup(String condition)
	{
		String sql 					=	" select a.ent_code,a.group_admin_flag,a.ent_group_id " +
										" from enterprise a where 1=1 " +
										condition+" " +
										" and a.ent_group_id in " +
										" (select b.ent_group_id from enterprise b " +
										"    where b.state = '1' and  b.ent_group_id is not null ) " +
										" and a.state='1'" +
										" order by a.ent_group_id ";
		//这里有个问题，就是集团管理员的问题，后续再考虑吧，即集团管理员的企业必须有效
		return sql;
	}
	//add at 20120328 增加企业状态state和企业用户状态缓存sub_state
	private static String genSqlEnterprise(String condition)
	{
		String sql 					=	" select a.ent_code,a.ent_name,a.state,a.sub_state,a.flag, " +
										" a.ent_group_id " +
										" from enterprise a where 1=1 " +
										condition+" order by a.ent_code ";//
		return sql;
	}
	private static String genSqlTriggerPhone(String condition)
	{
		String sql 					=	" select distinct c.ent_code ent_code,a.order_sn sub_id,c.sms_temple_id sm_temple_id," +
											" c.sms_temple_context sm_temple_context, " +
											//add at 20120429 短信每天发送的起始时间
											" c.s_start_time s_start_time,c.s_end_time s_end_time," +
											//modified at 20120219 如果是特服号码，则区号不取
											" b.area_no||b.phone_num order_num," +//decode(b.special_serv_flag,'1','',b.area_no)  20120513 不需要管特服标志
											" c.audit_flag audit_flag, c.cdr_type cdr_type ," +
											" a.alarm_num alarm_num,a.out_price_times out_price_times, " +
											" a.in_price_times in_price_times ,a.send_flag send_flag,"+//d.group_id group_id,d.group_type group_type , ,a.alarm_context alarm_context
											" nvl(b.true_VOUCH_NUMBER,b.area_no||to_char(a.VOUCH_NUMBER)) true_VOUCH_NUMBER, a.special_serv_flag special_serv_flag" +//,a.physical_num physical_num
											//add at 20120212 增加计费号码、特服标志、物理号码（注释掉 20120219）三个字段
											" ,c.state temple_state " +
											" ,c.rules_ins_id rules_ins_id" +
											" ,a.state dh_state,a.wp_state wp_state,a.wp_in_price_times wp_in_price_times " +
											" ,a.wp_out_price_times wp_out_price_times "+
											" from order_info a,trigger_phone b,sms_templete c" +//,sms_temple_group d 
											" where b.sms_temple_id = c.sms_temple_id  " +
											" and a.ent_code=c.ent_code   " +
											" and (a.state='1' or a.wp_state='1') and b.state='1' " +
											" and c.temple_type='1' " +
											//add at 20120523 群发模版=2，拦截模版=1，只加载拦截模版
											//modify at 20120425 增加条件 or a.wp_state='1'
											condition+
											"  " +//and d.sms_temple_id=c.sms_temple_id
											" order by c.sms_temple_id,a.order_sn desc ";//,d.group_type
		return sql;
	}
	private static String genTempleGroup(String condition)
	{
		String sql 					=	" select  t.sms_temple_id sms_temple_id,t.group_type group_type,t.group_id group_id ," +//客户群组
											" t.mobile_num mobile_num ,t.ent_code ent_code from (" +
											" select distinct d.sms_temple_id sms_temple_id,d.group_type group_type,d.group_id group_id ," +
											" a.mobile_num mobile_num ,a.ent_code ent_code" +
											" from customer a ,cust_group_member b,customer_group c,sms_temple_group d " +
											" where a.cust_code=b.cust_code and b.group_id=c.group_id " +
											" and c.group_id = d.group_id and  a.cust_type ='1' "+
											condition+
											" union " +//默认群组
											" select distinct c.sms_temple_id sms_temple_id,c.group_type group_type,c.group_id group_id, " +
											" 'A0' mobile_num,a.ent_code ent_code " +
											" from sms_templete a ,sms_temple_group c " +
											" where a.audit_flag='1' and a.state='1' " +
											" and a.sms_temple_id = c.sms_temple_id and c.group_type='0' " +
											condition+
											" )t " +
											" order by t.sms_temple_id,t.ent_code, t.group_type desc" +
											" ";
		return sql;
	}
	private static String genSqlWhite(String condition)
	{
		String sql 					=	" select  a1.ent_code ent_code,a1.mobile_num mobile_num" +
											" from  customer a1 " +
											" where a1.cust_type ='2' " +
											condition+
											" order by   a1.ent_code,a1.mobile_num desc" +
											"  ";
		return sql;
	}
	private static void setVmode()throws BaseException
	{
		///////////add at 20120501
		try
		{
			vLogger.info("====================init start :get CACHE_MODE ====================");
			BusiObj confBo 	= 	Configuration.getConfBO();
			BusiObj bo 		= 	confBo.getBusiObj("CACHE_MODE");
			vMode			=	bo.getInt("VMODE","1");
			vMaster			=	System.getProperty("VSoft.CacheMaster") ;
			if(vMaster == null)
				vMaster = "0";
			vLogger.info("====================end get CACHE_MODE="+vMode+" ====================");
		}
		catch(Throwable e)
		{
			e.printStackTrace();
			throw new BaseException(vName +"-101","缓存初始化获取缓存方式失败，请检查系统配置文件："+e.getMessage());
		}
	}
	private void init_temple(Connection conn,String sqlCond) throws BaseException
	{
		long put_start_time=System.currentTimeMillis();
		long put_end_time=0L;
		put_start_time=System.currentTimeMillis();
		
		String sql 						=	TableCacheServer.genSqlTriggerPhone(sqlCond);
		SQLArgs 	Arg					= 	new SQLArgs();
		Arg.reset();
		vLogger.info("initialize cache (1)query smsTemple  sql:" +sql);
		BusiObj		smsTempleBo 		= OperAgent.execQuery(conn, "getSubscriberAndSMSTemple", sql, Arg,true);
		//vLogger.info("返回数据是 initialize cache(1)query smsTemple:" + BOHelper.boToXML(smsTempleBo));
		//	 	GROUP_TYPE： 0：默认；1，客户群组；2：企业白名单
		Arg.reset();
		//处理短信模板，key=被叫号码，即触发电话
		HashMap<String,ArrayList<BusiObj>> haTemp = null;
		HashMap<String,HashMap<String,String>> hmTemp = null;
		
		ArrayList<BusiObj> alSms		=	smsTempleBo.getBusiObjList(RESULT);
		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vData(0) --query data from db over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================共"+alSms.size()+"条记录。");
		String order_num				= "";
		int iSmsCnt						=	0;
		if(haTemp == null)
			haTemp 						=	new HashMap<String,ArrayList<BusiObj>>();
		else
			haTemp.clear();		
		for(BusiObj m:alSms)
		{
			order_num = m.getString("order_num");
			ArrayList<BusiObj> AlBo		=	haTemp.get(order_num);
			if(AlBo==null)
				AlBo					=	new	ArrayList<BusiObj>();
			//m	=	TableCacheServer.formatAlarmContext(m);
			AlBo.add(m);
			haTemp.put(order_num, AlBo);//+i
			iSmsCnt++;
		}
		putArData(vData,haTemp);
		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vData(0) --put into cache over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================初始化短信模版共："+iSmsCnt+"条。");
		
		freeResource(haTemp, hmTemp,smsTempleBo,alSms);
/*		smsTempleBo						=	null;
		alSms							=	null;*/
	}
	//add at 20121229 
	private void init_temple_group(Connection conn,String sqlCond) throws BaseException
	{
		long put_start_time				=	System.currentTimeMillis();
		long put_end_time				=	0L;
		String	sql						=	TableCacheServer.genTempleGroup(sqlCond);
		vLogger.info("initialize cache (2)query smsTempleGroup  sql:" +sql);
		SQLArgs 	Arg					= 	new SQLArgs();
		Arg.reset();
		BusiObj		templeGroupBo 		= OperAgent.execQuery(conn, "smsTempleGroup", sql, Arg,true);
		//vLogger.info("返回数据是 initialize cache(2)query smsTempleGroupAndWhite :" + BOHelper.boToXML(templeGroupBo));
		//处理模板群组,key=sms_temple_id
		///////////////////////////////////////		
		//两个临时变量
		HashMap<String,ArrayList<BusiObj>> haTemp = null;
		HashMap<String,HashMap<String,String>> hmTemp = null;
		ArrayList<BusiObj> alTempleGroup				=	templeGroupBo.getBusiObjList(RESULT);		
		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vTempleGroupData(2) --query data from db over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================共"+alTempleGroup.size()+"条记录。");
		//处理模板群组,key=sms_temple_id
		 put_start_time=System.currentTimeMillis();
		String group_type ="",group_id="",sms_temple_id="",mobile_num="",ent_code="";
		int iTempleGroupCnt				=	0;		
		if(haTemp == null)
			haTemp = new HashMap<String,ArrayList<BusiObj>>();
		else
			haTemp.clear();
		for(BusiObj m:alTempleGroup)
		{
			group_type					=	m.getString("group_type");
			group_id					=	m.getString("group_id");
			sms_temple_id				=	m.getString("sms_temple_id");
			mobile_num					=	m.getString("mobile_num");//A0,默认群组
			ent_code					=	m.getString("ent_code");

			ArrayList<BusiObj> AlBo		=	haTemp.get(sms_temple_id);
			if(AlBo==null)
				AlBo					=	new	ArrayList<BusiObj>();
			AlBo.add(m);
			haTemp.put(sms_temple_id, AlBo);//+i
			iTempleGroupCnt++;
		}
		putArData(vTempleGroupData,haTemp);

		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vTempleGroupData(2) --put into cache  over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================初始化短信模版群组信息："+iTempleGroupCnt+"条。");
		
		freeResource(haTemp, hmTemp,templeGroupBo,alTempleGroup);
/*		templeGroupBo					=	null;
		alTempleGroup					=	null;*/
	}
	//add at 20121229 
	private void init_white(Connection conn,String sqlCond) throws BaseException
	{
		long put_start_time=System.currentTimeMillis();
		long put_end_time=0L;
		//白名单
 		String	sql						=	TableCacheServer.genSqlWhite(sqlCond);
		SQLArgs 	Arg					= 	new SQLArgs();
 		Arg.reset();
		vLogger.info("initialize cache (3)query WhiteList  sql:" +sql);
		BusiObj		whiteListBo 		= OperAgent.execQuery(conn, "WhiteList", sql, Arg,true);
		//vLogger.info("返回数据是 initialize cache (3)query WhiteList :" + BOHelper.boToXML(whiteListBo));
		//处理白名单，key=手机号码，即主叫号码
		HashMap<String,ArrayList<BusiObj>> haTemp = null;
		HashMap<String,HashMap<String,String>> hmTemp = null;
		ArrayList<BusiObj> alWhite		=	whiteListBo.getBusiObjList(RESULT);
		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vWhiteListData(1)   --query data from db over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================共"+alWhite.size()+"条记录");
		//================打入缓存==========
		put_start_time=System.currentTimeMillis();
		int	iWhiteCnt					=	0;
		HashMap<String,String>	hWhiteList = null;
		String group_type ="",group_id="",sms_temple_id="",mobile_num="",ent_code="";
		hmTemp 							=	new HashMap<String,HashMap<String,String>>();
		for(BusiObj m:alWhite)
		{
			mobile_num					=	m.getString("mobile_num");
			ent_code					=	m.getString("ent_code");
			//ArrayList<BusiObj> AlBo			=	vWhiteListData.get(ent_code);
/*			if(AlBo==null)
				AlBo										=	new	ArrayList<BusiObj>();
			AlBo.add(m);
			vWhiteListData.put(ent_code, AlBo);//+i
*/			//modify at 20120426 ArrayList<BusiObj>改成HashMap<String,String>
			hWhiteList 					=	hmTemp.get(ent_code);
			if(hWhiteList==null)
				hWhiteList				=	new HashMap<String,String>();
			hWhiteList.put(mobile_num, "1");
			hmTemp.put(ent_code, hWhiteList);
			iWhiteCnt++;
		}
		putHmData(vWhiteListData,hmTemp);

		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vWhiteListData(1)  --put into cache  over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================初始化白名单共："+iWhiteCnt+"条。");
		
		freeResource(haTemp, hmTemp,whiteListBo,alWhite);
/*		alWhite							=	null;
		whiteListBo						=	null;*/
	}
	//add at 20121229 
	private void init_enterprise(Connection conn,String sqlCond) throws BaseException
	{
		long put_start_time				=	System.currentTimeMillis();
		long put_end_time				=	0L;
		///////////////////////////////////////
		//add at 20120328	企业状态和企业用户状态
 		String	sql						=	TableCacheServer.genSqlEnterprise(sqlCond);
 		SQLArgs 	Arg					= 	new SQLArgs();
 		Arg.reset();
		vLogger.info("initialize cache (4)query enterprise  sql:" +sql);
		BusiObj	enterpriseListBo 		= OperAgent.execQuery(conn, "enterpriseList", sql, Arg,true);
		//vLogger.info("返回数据是 initialize cache (4)query enterpriseList :" + BOHelper.boToXML(enterpriseListBo));
		///////////////////////////////////////
		///////////////////////////////////////
		//add at 20120328	企业状态和企业用户状态
		HashMap<String,ArrayList<BusiObj>> haTemp = null;
		HashMap<String,HashMap<String,String>> hmTemp = null;
		ArrayList<BusiObj> alEnterprise	=	enterpriseListBo.getBusiObjList(RESULT);
		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vEnterpriseData(3) --query data from db  over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================共"+alEnterprise.size()+"条记录。");
		put_start_time=System.currentTimeMillis();

		int	iEntCnt						=	0;
		if(haTemp == null)
			haTemp 						= new HashMap<String,ArrayList<BusiObj>>();
		else
			haTemp.clear();
		
		for(BusiObj m:alEnterprise)
		{
			String entCode 				=	m.getString("ent_code");//
			ArrayList<BusiObj> AlBo		=	haTemp.get(entCode);
			if(AlBo==null)
				AlBo					=	new	ArrayList<BusiObj>();
			AlBo.add(m);
			haTemp.put(entCode, AlBo);//+i
			iEntCnt++;
		}
		//}
	
		putArData(vEnterpriseData,haTemp);
		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vEnterpriseData(3) --put into cache over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================初始化企业信息，共："+iEntCnt+"条");
		freeResource(haTemp, hmTemp,enterpriseListBo,alEnterprise);
/*		enterpriseListBo				=	null;
		alEnterprise					=	null;*/
	}
	//add at 20121229 
	//保险起见，还是释放下
	private static void freeResource(HashMap<String,ArrayList<BusiObj>> haTemp,
			HashMap<String,HashMap<String,String>>hmTemp,
			BusiObj bo,ArrayList<BusiObj> alBo)throws BaseException
	{
		alBo							=	null;
		bo								=	null;
		if(haTemp != null)
		{
			haTemp.clear();
			haTemp						=	null;
		}
		if(hmTemp != null)
		{
			hmTemp.clear();
			hmTemp						=	null;
		}
		System.gc();
	}
	//add at 20121229 
	private void init_enterprise_group(Connection conn,String sqlCond) throws BaseException
	{
		long put_start_time				=	System.currentTimeMillis();
		long put_end_time				=	0L;
		//add at 20120428	企业集团与企业关系缓存
 		String	sql						=	TableCacheServer.genSqlEnterpriseGroup(sqlCond);
 		SQLArgs 	Arg					= 	new SQLArgs();
 		Arg.reset();
		vLogger.info("initialize cache (5)query enterpriseGroup  sql:" +sql);
		BusiObj	enterpriseGroupBo 		=	OperAgent.execQuery(conn, "enterpriseGroup", sql, Arg,true);
		///////////////////////////////////////
		//add at 20120428	企业状态和企业用户状态
		HashMap<String,ArrayList<BusiObj>> haTemp = null;
		HashMap<String,HashMap<String,String>> hmTemp = null;
		ArrayList<BusiObj> alEnterpriseGroup	=	enterpriseGroupBo.getBusiObjList(RESULT);
		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vEnterpriseGroupData(4)--query data from db   over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================共"+alEnterpriseGroup.size()+"条记录。");
		put_start_time					=	System.currentTimeMillis();

		int	iEntGroupCnt				=	0;
		if(hmTemp == null)
			hmTemp 						=	new HashMap<String,HashMap<String,String>>();
		else
			hmTemp.clear();
		for(BusiObj m:alEnterpriseGroup)
		{
			String entCode 						=	m.getString("ent_code");//a.group_admin_flag,a.ent_group_id
			String entGroupId 					=	m.getString("ent_group_id");
			String group_admin_flag 			=	m.getString("group_admin_flag");
			HashMap<String,String>	hEntGroup	=	vEnterpriseGroupData.get(entGroupId);
			
			if(hEntGroup==null)
				hEntGroup				=	new HashMap<String,String>();
			hEntGroup.put(entCode, group_admin_flag);
			vEnterpriseGroupData.put(entGroupId, hEntGroup);
			iEntGroupCnt++;
		}
		putHmData(vEnterpriseGroupData,hmTemp);
		//}
		put_end_time					=	System.currentTimeMillis();
		vLogger.info("====================init put vEnterpriseGroupData(4)--put into cache  over" +
				"耗时："+(put_end_time-put_start_time) +
				"====================初始化企业集团关系信息，共"
				+iEntGroupCnt+"条。");
		///////////////////////////////////////
		freeResource(haTemp, hmTemp,enterpriseGroupBo,alEnterpriseGroup);
/*		enterpriseGroupBo				=	null;
		alEnterpriseGroup				=	null;*/
	}
	public static void  init(Connection conn) throws BaseException//BusiObj
	{
		vLogger.info("====================init start====================");
		///////////add at 20120501
		setVmode();
		////////////////
		try
		{
			if(TableCacheServer.checkIsInit() )//已初始化，则清除缓存
			{
				if(vMode ==1 ||(vMode==2&&vMaster.equals("1")))
				{
					vData.clear(); //可以用于刷新
					vWhiteListData.clear(); //可以用于刷新
					vTempleGroupData.clear(); //可以用于刷新
					vEnterpriseData.clear();//add at 20120331
					vEnterpriseGroupData.clear();//add at 20120428
					
					//redList不清除，因为不是从数据库load 20121209
				}
			}
			else//初始化缓存
			{
				if(vMode == 1)
				{
					vData				=	new GenericProxy<ArrayList<BusiObj>>();
					vWhiteListData		=	new GenericProxy<HashMap<String,String>>();
					//modify at 20120426 ArrayList<BusiObj>改成HashMap<String,String>
					vTempleGroupData	=	new GenericProxy<ArrayList<BusiObj>>();
					vEnterpriseData		=	new GenericProxy<ArrayList<BusiObj>>();//add at 20120331
					vEnterpriseGroupData=	new GenericProxy<HashMap<String,String>>();//add at 20120428
					
					vConfigListData		=	new GenericProxy<HashMap<String,String>>();//add at 20121209
				}else
				{
					boolean bClear 		=	vMaster.equals("1")?true:false;
					vLogger.debug("init redis var ,and need clear:"+bClear);
					vData				=	new RedisProxy<ArrayList<BusiObj>>();
					vData.setId(0,bClear);
					vData.setType(1);
					vWhiteListData		=	new RedisProxy<HashMap<String,String>>();
					vWhiteListData.setId(1,bClear);
					vWhiteListData.setType(3);
					//modify at 20120426 ArrayList<BusiObj>改成HashMap<String,String>
					vTempleGroupData	=	new RedisProxy<ArrayList<BusiObj>>();
					vTempleGroupData.setId(2,bClear);
					vTempleGroupData.setType(1);
					vEnterpriseData		=	new RedisProxy<ArrayList<BusiObj>>();//add at 20120331
					vEnterpriseData.setId(3,bClear);
					vEnterpriseData.setType(1);
					vEnterpriseGroupData=	new RedisProxy<HashMap<String,String>>();//add at 20120428
					vEnterpriseGroupData.setId(4,bClear);
					vEnterpriseGroupData.setType(3);
					
					vConfigListData		=	new RedisProxy<HashMap<String,String>>();
					vConfigListData.setId(5,false);
					vConfigListData.setType(3);
				}	
			}
			if(vMode == 2 && vMaster.equals("1") == false){
				vLogger.info("Redis mode :不是master，忽略");				
				return;
			}
			//add at 20120331
			String 	sqlCond=	"  ";// and rownum<50 
			long start_time=System.currentTimeMillis();
			//add at 20120408 debug模式
			if(flagDebug)
			{
				sqlCond					=	" and rownum<50  ";
				vLogger.info("---------------flagDebug=true");
			}
			else
				vLogger.info("---------------flagDebug=false");
			//add at 20120408 debug模式
			
			//add at 20121229,减少内存占用，先使用拆分方法，看能否解决问题。
			//1  temple_group
			TableCacheServer	cacheServer	=	new TableCacheServer();
			cacheServer.init_temple_group(conn, sqlCond);
			//2  whiteList
			cacheServer.init_white(conn, sqlCond);
			//3  temple
			cacheServer.init_temple(conn, sqlCond);
			//4  enterprise
			cacheServer.init_enterprise(conn, sqlCond);
			//5  enterprise_group
			cacheServer.init_enterprise_group(conn, sqlCond);
			cacheServer	=	null;
			long end_time=System.currentTimeMillis();
			vLogger.info("====================初始化模版缓存耗时："+(start_time-end_time)+"====================");
		}
		catch(Throwable e)
		{
			vLogger.debug(LogCollect.getStackLog(e));//add at 20120524
			e.printStackTrace();
			throw new BaseException(vName +"-001","模版数据初始化失败。"+e.getMessage());
		}
		vLogger.info("====================init end====================");

		// and c.audit_flag='1' and c.eff_date<=sysdate and c.exp_date>=sysdate
	}
	private static void putArData(ICacheObj<ArrayList<BusiObj>>  cacheobj,HashMap<String,ArrayList<BusiObj>> data) throws BaseException
	{
		Iterator<String> itKey = null;
		String strKeyName = null;
		
		cacheobj.setPipeline(true);
		itKey = data.keySet().iterator();
		while(itKey.hasNext()){
			strKeyName = itKey.next();
			cacheobj.put(strKeyName, data.get(strKeyName));
		}
		cacheobj.setPipeline(false);
	}
	
	private static void putHmData(ICacheObj<HashMap<String,String>>  cacheobj,HashMap<String,HashMap<String,String>> data) throws BaseException
	{
		Iterator<String> itKey = null;
		String strKeyName = null;
		
		cacheobj.setPipeline(true);
		itKey = data.keySet().iterator();
		while(itKey.hasNext()){
			strKeyName = itKey.next();
			cacheobj.put(strKeyName, data.get(strKeyName));
		}
		cacheobj.setPipeline(false);
	}
	
	private static BusiObj formatAlarmContext(BusiObj m) throws BaseException
	{
		String alarm_context	=	m.getString("alarm_context","");
		String	in_price_times	=	m.getString("in_price_times","");
		if(alarm_context.trim().equals("")||in_price_times.trim().equals(""))
		{
			alarm_context="挂机短信本月发送已超过限制";
		}
		else
		{
			alarm_context=String.format(alarm_context,Integer.parseInt(in_price_times));
		}
		m.setString("alarm_context", alarm_context);
			
		return m;
	}
	private static  boolean checkIsInit()
	{
		if(vData==null||vTempleGroupData==null||vWhiteListData==null||vEnterpriseData==null)
			//20120428这里不能加上新增的vEnterpriseGroupData，因为vEnterpriseGroupData真的有可能是null
			return false;
		else
			return true;
		
	}

	private static  void  removeCacheByEntcode(BusiObj bo) throws BaseException
	{
		//20120405 需考虑400号码和模版被删除的情况  
		String ent_code			=	bo.getString("ent_code");
		Connection conn			=	bo.getConnection();
		String sql 				= 	" select a.sms_temple_id sms_temple_id ," +
									" b.area_no||b.phone_num order_num  " +
									//decode(b.special_serv_flag,'1','',b.area_no) 20120513 不需要处理特服号码
									" from sms_templete a,trigger_phone b " +
									" where a.sms_temple_id=b.sms_temple_id and a.ent_code=:ent_code";
		SQLArgs 	Arg			= 	new SQLArgs();
		Arg.reset();
		Arg.setArg("ent_code", ent_code);
		vLogger.info("removeCacheByEntcode sql:" +sql);
		BusiObj		smsTempleBo 			= 	OperAgent.execQuery(conn, "removeCacheByEntcode", sql, Arg);
		vLogger.info("返回数据是 removeCacheByEntcode:  " + BOHelper.boToXML(smsTempleBo));
		ArrayList<BusiObj> alTemple			=	smsTempleBo.getBusiObjList(RESULT);
		//TODO 需考虑删除集团与企业关系缓存 20120428，已在外面刷新，故不需在这里刷新。
		
		////////////////////add at 20120328  remove enterprise
		vEnterpriseData.remove(ent_code);
		vLogger.info("删除缓存（1）--企业信息部分：企业编码="+ent_code);
		/////////////////////////////remove whiteList
		vWhiteListData.remove(ent_code);
		vLogger.info("删除缓存（2）--白名单信息部分：企业编码="+ent_code);
		/////////////////////////////remove order_num and group
		HashMap <String,String> hOrder 		= 	new HashMap <String,String> ();
		HashMap <String,String> hTemple 	= 	new HashMap <String,String> ();
		if(alTemple!=null)
		{
			for(BusiObj m:alTemple)
			{
				String 	sms_temple_id 		= 	m.getString("sms_temple_id");
				String	order_num			=	m.getString("order_num");
				String	sOrder				=	hOrder.get(order_num);
				if(sOrder==null)
				//hash中取不到值，即为null
				//如果hash中该key取值不为空，则说明已进行过remove操作，不需要再处理
				{
					vData.remove(order_num);
					hOrder.put(order_num, "1");
				}
				String	sTemple				=	hTemple.get(sms_temple_id);
				if(sTemple==null)
				//hash中取不到值，即为null
				//如果hash中该key取值不为空，则说明已进行过remove操作，不需要再处理
				{
					vTempleGroupData.remove(sms_temple_id);
					hTemple.put(sms_temple_id, "1");
				}
			}
		}
		TableCacheServer.removeCacheTempleAndGroupByEndcode(ent_code, conn, Arg);
		
	}
	private static void removeCacheTempleAndGroupByEndcode(String ent_code,Connection conn,SQLArgs Arg) throws BaseException
	{
		//add at 20120405 模版被删除需另外从order info中找///////////////////////////remove order_num and group
		{
			String sql=	" select a.vouch_number vouch_number,a.area_code area_code,b.area_no area_no, " +
						" a.true_vouch_number true_vouch_number,a.special_serv_flag special_serv_flag, " +
						" a.state state " +
						" from order_info a,area b " +
						" where a.area_code=b.cat_code and  a.ent_code=:ent_code ";
			Arg.reset();
			Arg.setArg("ent_code", ent_code);
			vLogger.info("removeCacheTempleteByEntcode sql:" +sql);
			BusiObj		orderInfoBo 		= 	OperAgent.execQuery(conn, "removeCacheTempleteByEntcode", sql, Arg);
			vLogger.info("返回数据是 removeCacheTempleteByEntcode: " + BOHelper.boToXML(orderInfoBo));
			ArrayList<BusiObj> alOrder		=	orderInfoBo.getBusiObjList(RESULT);
			for(BusiObj orderBo: alOrder)
			{
				String	vouch_number		=	orderBo.getString("vouch_number");
				String	area_no				=	orderBo.getString("area_no");
				String	area_code			=	orderBo.getString("area_code");
				String	true_vouch_number	=	orderBo.getString("true_vouch_number");
				String	special_serv_flag	=	orderBo.getString("special_serv_flag");
				String	state				=	orderBo.getString("state");
				String	order_num			=	"";
/*				if(TableCacheServer.isStrNullOrEmpty(special_serv_flag)
						||!(special_serv_flag.trim().equals("1")))*/
					//特服标志不等于1，则不取区号
				//////////////////////////////add at 20120831 手机号码则不取区号
				boolean	bMobile	=	CmPublic.isMobileNum(vouch_number);
				if(bMobile)
					order_num				=	vouch_number;
				else
				//////////////////////////////add at 20120831 end
				{
					
					order_num				=	area_no+vouch_number;
				}
/*				else
					order_num				=	vouch_number;*/
				ArrayList<BusiObj> alTempleInOrderNum=vData.get(order_num);
				if(alTempleInOrderNum==null)
					continue;
				for(BusiObj templeBo:alTempleInOrderNum)
				{
					String templeId			=	templeBo.getString("sm_temple_id");//注意这个字段
					vTempleGroupData.remove(templeId);
					vLogger.info("删除企业缓存--模版群组部分：企业编码="+ent_code+"；的触发号码="+order_num+"；模版编码="+templeId);
				}
				vData.remove(order_num);
				vLogger.info("删除企业缓存--模版部分：企业编码="+ent_code+"；的触发号码="+order_num);
			}
		}
	}
	//检查企业是否有效
	private static  boolean checkEntValid(BusiObj bo) throws BaseException
	{
		String ent_code			=	bo.getString("ent_code");
		Connection conn			=	bo.getConnection();
		String sql 				= 	" select count(1) from enterprise where state='1' and ent_code =:ent_code";
		SQLArgs 	Arg			= 	new SQLArgs();
		Arg.reset();
		Arg.setArg("ent_code", ent_code);
		vLogger.info("check enterprise is valid  sql:" +sql);
		int cnt 				= 	OperAgent.QueryInt(conn, "checkEntValid", sql, Arg);
		vLogger.info("返回数据是 checkEntValid:" + cnt);
		
		if(cnt<1)
			return false;//无有效企业
		else
			return true;
		
	}
	public static boolean isStrNullOrEmpty(String str)
	{
		boolean flag =false;
		if(str ==null || str.trim().equals(""))
			flag=true;
		return flag;
	}
	public static String getOneStaticValue(BusiObj bo)throws BaseException
	{
		Connection conn 		=	bo.getConnection();
		String table_name=bo.getString("table_name");
		SQLArgs 	Arg			= 	new SQLArgs();
 		String sql				=	"select a.code from static_data a where upper(a.table_name )=:table_name";
 		Arg.reset();
		vLogger.debug("query static data :  sql:" +sql);
		Arg.setArg("table_name", table_name);
		BusiObj		staticBo 	= OperAgent.execQuery(conn, "query static data", sql, Arg);
		vLogger.debug("返回数据是 query static data ::" + BOHelper.boToXML(staticBo));
		String rt				=	"";	
		ArrayList<BusiObj> Al_bos = staticBo.getBusiObjList(RESULT);
		//多余一条记录仅取第一条，否则返回空串
		if(Al_bos.size()>0)
		{
			BusiObj BO=Al_bos.get(0);
			rt=BO.getString("code");
		}

		return rt;
	}
	public static BusiObj getTempleForSend(BusiObj bo) throws BaseException
	{
		BusiObj retBo			=	new BusiObj();
		vLogger.info("====================getTempleForSend start====================");
		retBo					=	TableCacheServer.getTempleForSendIn(bo);
		vLogger.info( "getTempleForSend返回数据："+BOHelper.boToXML(retBo));
		vLogger.info("====================getTempleForSend end====================");
		return retBo;
	}
	private static BusiObj genFailerMsg(String msg) throws BaseException
	{
		BusiObj retBo=new BusiObj();
		retBo.setString("desc",msg);//
		retBo.setValue(RESULT,new ArrayList<BusiObj>());
		return retBo;
	}
	//add at 20120523
	public static void setDebugFlag(String debugFlag) throws BaseException
	{
		BusiObj	bo	=	new BusiObj();
		bo.setString("debugFlag", debugFlag);
		setDebugFlag(bo);
	}
	//add at 20120408 add debugFlag
	private static void setDebugFlag(BusiObj bo) throws BaseException
	{
		String debugFlag	=	bo.getString("debugFlag","");
		vLogger.info("========================debugFlag="+debugFlag);
		if(debugFlag.trim().equals("1"))
			flagDebug		=	true;
		else
			flagDebug		=	false;
	}
	private static String trans(String value) throws BaseException
	{
		String retValue		=	"0";
		if(!CmPublic.isStrNullOrEmpty(value))
			retValue		=	value.trim();
		return	retValue;
	}
	//add at 20120429 判断拦截时间是否在发送时间段内
	//1、起始时间嘦一个为空，则返回true，即可发
	private static boolean checkInterceptTimeCanSend(BusiObj bo,String	timeNow) throws BaseException
	{
		try
		{
			boolean	sendFlag		=	false;
			String	s_end_time		=	bo.getString("s_end_time","");
			String	s_start_time	=	bo.getString("s_start_time","");
			int				length	=	4;
			if(!TableCacheServer.checkStringNumberLength(s_end_time,length)
					||!TableCacheServer.checkStringNumberLength(s_start_time,length)
					||!TableCacheServer.checkStringNumberLength(timeNow,length))
				sendFlag			=	true;
			else
			{
				int	timeNowHour		=	Integer.valueOf(timeNow.substring(0,2));
				int	s_start_timeHour=	Integer.valueOf(s_start_time.substring(0,2));
				int	s_end_timeHour	=	Integer.valueOf(s_end_time.substring(0,2));
				int	timeNowMin		=	Integer.valueOf(timeNow.substring(2,4));
				int	s_start_timeMin	=	Integer.valueOf(s_start_time.substring(2,4));
				int	s_end_timeMin	=	Integer.valueOf(s_end_time.substring(2,4));
				if((timeNowHour>s_start_timeHour||(timeNowHour==s_start_timeHour &&timeNowMin>=s_start_timeMin))
						&&(timeNowHour<s_end_timeHour||(timeNowHour==s_end_timeHour &&timeNowMin<=s_end_timeMin)))
					sendFlag			=	true;
			}
			return	sendFlag;
		}
		catch(Throwable e)
		{
			vLogger.debug(LogCollect.getStackLog(e));//add at 20120524
			e.printStackTrace();
			return true;
		}
	}
	public static boolean isNumeric(String str)
	{
		if(CmPublic.isStrNullOrEmpty(str))
			return false;
	    for(int i=str.length();--i>=0;)
	    {
	      int chr=str.charAt(i);
	      if(chr<48 || chr>57)
	         return false;
	    }
	    return true;
	}

	//返回值：成功--true
	private static boolean checkStringNumberLength(String	str,int length) throws BaseException
	{
		boolean	flag		=	false;
		if(TableCacheServer.isNumeric(str)
				&&str.trim().length()==length)
		{
			flag		=	true;
		}
		return	flag;
	}
	
	private static BusiObj getTempleForSendIn(BusiObj bo) throws BaseException
	{
		String	timeNow		=	CmPublic.genDateTimeFormat("HHmm");
		String desc ="";
		String order_num="";
		String mobile_num="";
		String cdr_type	="";
		String cdr_type_name="";
		String	ent_code	=	"",group_type="";
		String prompt="";
		BusiObj retBo=new BusiObj();
		try
		{
			Connection conn	=	bo.getConnection();
			//add at 20120408 增加debug标志
			TableCacheServer.setDebugFlag(bo);
			
			if(!TableCacheServer.checkIsInit())//未初始化
			{
				
				TableCacheServer.init(conn);
				//throw new BaseException(vName +"-001","请初始化获取短信模板功能。");
			}
			String alarm_context ="";
			//获取alarm_context
			{
				BusiObj		StaticBO	=new BusiObj() ;
				StaticBO.setConnection(conn);
				StaticBO.setString("TABLE_NAME", "order_info.alarm_context".toUpperCase());
				alarm_context 	=	TableCacheServer.getOneStaticValue(StaticBO);
			}
			
	
			order_num	=	bo.getString("order_num");
			mobile_num	=	bo.getString("mobile_num");
			cdr_type	=	bo.getString("cdr_type").trim();//
			cdr_type_name=TableCacheServer.getCdrTypeName(cdr_type);
			/////////////////////////add at 20121209
			boolean isMobileNumRed	=	false;
			{
				String	isRedList	=	vConfigListData.hmGet("redlist",mobile_num);
				if(isRedList!=	null &&(isRedList.trim().equals("1")))
				{
					isMobileNumRed	=	true;
				}
			}
			/////////////////////////
			prompt=	"======查询触发电话："+order_num+" 主叫号码："+mobile_num+" 通话状态："+cdr_type+"("+cdr_type_name+")"+"的短信模板======";
			vLogger.info(prompt);
			
			HashMap<String,String> hAddedTempleId= new HashMap<String,String>();
			HashMap<String,String> hWhiteMobileNum= new HashMap<String,String>();
			//ArrayList<BusiObj> arWhiteList = null;
			HashMap<String,String>	hWhiteList= null;
			HashMap<String,String>	hEntGroup= null;
			ArrayList<BusiObj> arTempleGroup = null;
			String whiteTempleId="";
			//////////////////////////////////
			BusiObj logBo=new BusiObj();
			logBo.setConnection(conn);
			logBo.setString("order_num", order_num);
			logBo.setString("mobile_num", mobile_num);
			logBo.setString("cdr_type", cdr_type);

			//////////////////////////////////
			////////////////////////////////////开始业务处理
			ArrayList<BusiObj> arData = vData.get(order_num);//获取触发电话的缓存
			int	cnt=0;
			if (arData!=null)
				cnt=arData.size();
			int	i=0,whiteCnt=0,groupCnt=0,cdrTypeCnt=0,auditCnt=0,groupWhiteCnt=0;
			int	templeStateCnt	=	0;//add at 20120527
			int	sendTimeIntervalCnt=0;//add at 20120429 发送时间区间计数器
			//1、该触发电话是否配置模板
			if(arData == null||cnt==0)
			{
				desc= "触发电话:"+order_num+";    没有配置短信模板。";
				retBo	=	TableCacheServer.genFailerMsg(desc);
/*				retBo.setString("desc",desc);//
				retBo.setValue(RESULT,new ArrayList<BusiObj>());*/
				//vLogger.info( BOHelper.boToXML(retBo));
				return retBo;
			}
			//有模板
			else
			{
				String	entGroupId	=	"";
				/////////////////////////add at 20120328  增加企业状态判断
				for(BusiObj boEnt :arData)//遍历触发电话模板和群组
				{
					ent_code	=	boEnt.getString("ent_code");
					{
						ArrayList<BusiObj> arEnterprise = null;
						arEnterprise	=	vEnterpriseData.get(ent_code);
						String	retDesc	=	"";
						if(arEnterprise==null||arEnterprise.size()==0)
						{
							retDesc	=	"触发电话："+order_num+"没有找到对应的企业信息。";
							retBo	=	TableCacheServer.genFailerMsg(retDesc);
							return	retBo;
						}
						else//由于ent code是pk，因此实际上下面的循环只有一次
						{
							for(BusiObj bEnterprise:arEnterprise)
							{
								String	state		=	bEnterprise.getString("state");
								String	sub_state	=	bEnterprise.getString("sub_state");
								String	ent_name	=	bEnterprise.getString("ent_name");
								if(state.trim().equals("0"))//企业状态无效
								{
									retDesc	=	"触发电话："+order_num+"对应的企业状态为无效，企业名称："+ent_name;
									retBo	=	TableCacheServer.genFailerMsg(retDesc);
									return	retBo;
								}
								else if(state.trim().equals("1") && sub_state.trim().equals("0"))//企业状态暂停
								{
									retDesc	=	"触发电话："+order_num+"对应的企业状态为暂停，企业名称："+ent_name;
									retBo	=	TableCacheServer.genFailerMsg(retDesc);
									return	retBo;
								}
								entGroupId	=	bEnterprise.getString("ent_group_id");
							}
						}
					}
				}
				/////////////////////////add at 20120328   
				for(BusiObj m :arData)//遍历触发电话模板和群组
				{
					vLogger.info("(1)===============触发电话:"+order_num+"的模板："+ BOHelper.boToXML(m));
					//add at 20120429 模版增加开始发送时间和结束发送时间
					if(!TableCacheServer.checkInterceptTimeCanSend(m,timeNow))
					{
						vLogger.info("(10000)===============触发时间不在发送时间段内:"+timeNow
								+"   	s_start_time="+m.getString("s_start_time","")
								+"	s_end_time="+m.getString("s_end_time",""));
						continue;
					}
					sendTimeIntervalCnt++;
					/////////////////////////////
					
					String templeCdrType=m.getString("cdr_type");
					String audit_flag=m.getString("audit_flag");
			//2、该模板是否审核，如果cnt》0，即模板数》0而审核数==0，则出现无审核模板信息
					if(!audit_flag.trim().equals("1")
							&& !isMobileNumRed)//模板未审核  add at 20121209
						continue;
					if(!audit_flag.trim().equals("1") && isMobileNumRed)
					{
						vLogger.info("(2.0.89)===============被叫号码"+order_num+"短信模版未审核，但主叫号码"+mobile_num+"是RL。。");
					}
					auditCnt++;//模板审核计数器+1
					//过滤cdr type,如果cdr_type不适配，则短信模板计数器不会增加,但是cdrtype的计数器会+1
					if(!(templeCdrType.trim().equals("4")||templeCdrType.trim().equals(cdr_type)))
						continue;
					cdrTypeCnt++;
			//3、cdr_type是否匹配，如果cnt》0，即模板数》0而cdr_type匹配数==0，则出现无匹配模板
					ent_code	=	m.getString("ent_code");

					//group_type= m.getString("group_type");
					String smsTempleId	=	m.getString("sm_temple_id");
					
					/////////////////////////add at 20120527 增加模版状态判断
					String temple_state=m.getString("temple_state");
					if(!temple_state.trim().equals("1") 
							&& !isMobileNumRed)//add at 20121209
						continue;
					if(!temple_state.trim().equals("1") && isMobileNumRed)
					{
						vLogger.info("(2.0.90)===============被叫号码"+order_num+"短信模版无效，但主叫号码"+mobile_num+"是RL。。");
					}
					templeStateCnt++;
					
					/////////////////////////处理白名单/////////////////////////////
					
					//add at 20120428处理集团白名单
					boolean	groupWhiteFlag=false;//集团白名单标志 
					hEntGroup	=	vEnterpriseGroupData.get(entGroupId);
					if(hEntGroup!=null)
					{
						for(String	entGroupMemberEntCode:hEntGroup.keySet())
						{
							String	groupAdminFlag	=	hEntGroup.get(entGroupMemberEntCode);
							if(groupAdminFlag!=null&&groupAdminFlag.trim().equals("1"))//集团管理员标志
							{
								//判断集团白名单
								//hWhiteList=vWhiteListData.get(ent_code);
								//if(!(hWhiteList==null||hWhiteList.size()==0))//主叫存在白名单
								{
									//String	isWhiteList	=	hWhiteList.get(mobile_num);
									String	isWhiteList	=vWhiteListData.hmGet(ent_code,mobile_num);
									if(isWhiteList!=null &&(isWhiteList.trim().equals("1")))
										//vLogger.info("(2)===============主叫号码"+mobile_num+"为企业"+ent_code+"白名单：");
									{
										whiteTempleId = smsTempleId;
										hWhiteMobileNum.put(mobile_num, "0");//设置白名单手机号码
										groupWhiteCnt++;//集团白名单总数,每个模板都会校验主叫是否为白名单，如果该触发电话有多个模板，而主叫为该企业的白名单，则白名单总数=模板总数，如果该触发电话属于多个企业，则会取出另一企业的模板
										groupWhiteFlag	=	true;//设置集团白名单标志，只要这个电话是企业白名单，就跳过，白名单与模板无关
										vLogger.info("(2.0.98)===============主叫号码"+mobile_num+"为企业"+ent_code+"的集团："+entGroupId+"白名单：");
										break;//主叫号码是集团白名单，则退出集团白名单

									}
								}
							}
						}
					}
					
					if(groupWhiteFlag)//只要这个电话是企业集团白名单，就跳过该模板，白名单与模板无关，不再查询群组
					{
						groupWhiteFlag=false;
						continue;
					}
					//////////////////////////////
					
					boolean	whiteFlag=false;//白名单标志 
					vLogger.info("(2)===============判断主叫号码"+mobile_num+"是否为企业"+ent_code+"白名单：");
					//if(vMode == 1)
					{
						//hWhiteList=vWhiteListData.get(ent_code);//加载企业的白名单缓存
						//if(!(hWhiteList==null||hWhiteList.size()==0))//主叫存在白名单
						{
							//String	isWhiteList	=	hWhiteList.get(mobile_num);
							String	isWhiteList	=vWhiteListData.hmGet(ent_code,mobile_num);
							if(isWhiteList!=null &&(isWhiteList.trim().equals("1")))
								//vLogger.info("(2)===============主叫号码"+mobile_num+"为企业"+ent_code+"白名单：");
							{
								whiteTempleId = smsTempleId;
								hWhiteMobileNum.put(mobile_num, "0");//设置白名单手机号码
								whiteCnt++;//白名单总数,每个模板都会校验主叫是否为白名单，如果该触发电话有多个模板，而主叫为该企业的白名单，则白名单总数=模板总数，如果该触发电话属于多个企业，则会取出另一企业的模板
								whiteFlag	=	true;//设置白名单标志，只要这个电话是企业白名单，就跳过，白名单与模板无关
								vLogger.info("(2.0.99)===============主叫号码"+mobile_num+"为企业"+ent_code+"白名单：");
								//break;//主叫号码是白名单，则换一个模板
	
							}
		/*					for(BusiObj n :arWhiteList)
							{
								String white_mobile_num	=	n.getString("mobile_num");
								
								if(white_mobile_num==null ||(white_mobile_num.trim().equals("")))
								//白名单的企业不等于模板的企业，则为非白名单，跳过
								{
									continue;
								}
									
								vLogger.info("(2)===============号码"+white_mobile_num+"为企业"+ent_code+"白名单："+ BOHelper.boToXML(n));
								if(white_mobile_num.equals(mobile_num))
								//白名单的企业等于模板的企业，则为白名单，白名单计数+1
								{
									whiteTempleId = smsTempleId;
									hWhiteMobileNum.put(white_mobile_num, "0");//设置白名单手机号码
									whiteCnt++;//白名单总数,每个模板都会校验主叫是否为白名单，如果该触发电话有多个模板，而主叫为该企业的白名单，则白名单总数=模板总数，如果该触发电话属于多个企业，则会取出另一企业的模板
									whiteFlag	=	true;//设置白名单标志，只要这个电话是企业白名单，就跳过，白名单与模板无关
									vLogger.info("(2.0.99)===============主叫号码"+mobile_num+"为企业"+ent_code+"白名单：");
									break;//主叫号码是白名单，则换一个模板
		
								}
							}*/
						}
					}

					if(whiteFlag)//只要这个电话是企业白名单，就跳过该模板，白名单与模板无关，不再查询群组
					{
						whiteFlag=false;//add at 20110721
						continue;
					}
					/////////////////////////处理白名单完毕/////////////////////////////
					//白名单与模板群组处理有关的是hWhiteEnt（白名单企业hash）和whiteCnt（白名单计数器）
					/////////////////////////处理短信模板群组/////////////////////////////
					arTempleGroup=vTempleGroupData.get(smsTempleId);
					if((arTempleGroup==null||arTempleGroup.size()==0)//该模板没有模板群组,则跳过本次模板
							)//add 20121209
					{
						if(!isMobileNumRed)//add 20121209
						{
							vLogger.info("(3.0.1)===============模板id="+smsTempleId+"没有发送群组。");
							continue;
						}
						else//add 20121209
						{
							vLogger.info("(3.0.90)===============被叫号码"+order_num+"短信模版没有装载发送群组，但主叫号码"+mobile_num+"是RL。。");
							arTempleGroup =	new ArrayList<BusiObj>();
							BusiObj tempBo	=	new BusiObj();
							tempBo.setString("sms_temple_id", smsTempleId);
							tempBo.setString("group_type", "0");
							tempBo.setString("group_id", "0");
							tempBo.setString("mobile_num", "A0");
							tempBo.setString("ent_code", ent_code);
							arTempleGroup.add(tempBo);
						}

					}
					
					for(BusiObj j :arTempleGroup)
					{
						//String groupTempleId	=	j.getString("sms_temple_id");

						group_type				=	j.getString("group_type");
						String white_mobile_num	=	hWhiteMobileNum.get(mobile_num);
						String mobile			=	j.getString("mobile_num");
						vLogger.info("(3)===============触发电话"+order_num+"；模板id"+smsTempleId+"的发送群组："+ BOHelper.boToXML(j));
						if((white_mobile_num==null||white_mobile_num.trim().equals("")))//如果主叫非该企业白名单
						//该企业白名单不包含该主叫号码,则加入该模板记录
						{
							//两种情况则可加入：1、群组是默认群组，不需要匹配主叫；2、群组为客户群组，需要匹配主叫
							if(group_type.trim().equals("0")||mobile.trim().equals(mobile_num))
							{
								groupCnt++;//返回记录数+1
								if(hAddedTempleId.get(smsTempleId)==null)//相同的模板只加一次，不分默认群组还是客户群组
								{
									BusiObj formatSms =new BusiObj();
									String in_price_times 	= 	m.getString("in_price_times");
									/////////////////////////////////////////////////////
									//add at 20120425
									String	dh_state		=	TableCacheServer.trans( m.getString("DH_STATE",""));
									String	wp_state		=	TableCacheServer.trans( m.getString("WP_STATE",""));
									String	wp_in_price_times		=	TableCacheServer.trans( m.getString("WP_IN_PRICE_TIMES",""));
									String	wp_out_price_times		=	TableCacheServer.trans( m.getString("WP_OUT_PRICE_TIMES","0"));
									//modified at 20120601 该字段用作用户自定义发送限额
									if(wp_state.equals("1")&&dh_state.equals("1"))
										in_price_times		=	String.valueOf(Integer.parseInt(in_price_times) +Integer.parseInt(wp_in_price_times) );
									else if(wp_state.equals("1"))
										in_price_times		=	wp_in_price_times;
									//add at 20120601 如果用户自定义发送限额不等于0，则
									if(//! wp_out_price_times.equals("0")||
											Integer.parseInt(wp_out_price_times)>0)
										in_price_times	=	wp_out_price_times;
									
									BusiObj smsTempleSend	=	new BusiObj();
									BOHelper.MergeBO(smsTempleSend,m);
									smsTempleSend.setString("in_price_times", in_price_times);
									/////////////////////////////////////////////////////
									formatSms.setString("alarm_context", alarm_context);
									formatSms.setString("in_price_times", in_price_times);
									formatSms = TableCacheServer.formatAlarmContext(formatSms);
									String sms_context = formatSms.getString("alarm_context");
									smsTempleSend.setString("alarm_context", sms_context);
									retBo.setValue(RESULT, smsTempleSend);
									
									hAddedTempleId.put(smsTempleId, smsTempleId);//要考虑主叫号码是白名单的情况
									vLogger.info("(4)===============模板id:"+smsTempleId+"已加入本次返回结果。groupCnt="+groupCnt
											+";模版内容："+BOHelper.boToXML(smsTempleSend));//add at 20120425
								}
								else
								{
									vLogger.info("(10003)===============模板id:"+smsTempleId+"已加入本次返回结果，不再重复加入。groupCnt="+groupCnt);
								}
							}
							else
							{
								vLogger.info("(10002)===============group type(非默认群组):"+group_type+"群组成员电话:"+mobile+"；主叫电话"+mobile_num);
							}
						}
						else
						{
							vLogger.info("(10001)===============白名单电话:"+white_mobile_num);
						}
	
					}
					/////////////////////////处理短信模板群组完毕/////////////////////////////
				}
				/////////////////////////add at 20120527 moved at 20121208 把模板有效状态提示要放在审核状态提示之前
				if(templeStateCnt==0&&cnt>0)
				{
					desc	=	"触发电话："+order_num+"没有有效的短信模板";
					retBo	=	TableCacheServer.genFailerMsg(desc);
					return retBo;
				}
				////////////////////////
				//add at 20120429
				if(sendTimeIntervalCnt==0&&cnt>0)
				{
					desc ="触发电话："+order_num+"没有在指定发送时间区间内的模版。";
					retBo	=	TableCacheServer.genFailerMsg(desc);
					return retBo;
				}
				/////////////////////////
				if(auditCnt==0&&cnt>0)
				{
					desc	=	"触发电话："+order_num+"的短信模板未审核";
					retBo	=	TableCacheServer.genFailerMsg(desc);
/*					retBo.setString("desc", desc);//，待审核的短信模板共"+auditCnt+"条。
					retBo.setValue(RESULT,new ArrayList<BusiObj>());*/
					//vLogger.info( BOHelper.boToXML(retBo));
					return retBo;
				}

				if(cdrTypeCnt==0&&cnt>0)
				{
	/*				HashMap<String,String> cdrType= new HashMap<String,String>();
					cdrType.put("1", "忙");
					cdrType.put("2", "未接");
					cdrType.put("3", "通话");*/
					desc ="没有符合触发电话："+order_num+"本次通话状态:"+cdr_type+"("+cdr_type_name+")"+"的短信模板。";
					retBo	=	TableCacheServer.genFailerMsg(desc);
/*					retBo.setString("desc",desc );//
					retBo.setValue(RESULT,new ArrayList<BusiObj>());*/
					//vLogger.info( BOHelper.boToXML(retBo));
					return retBo;
				}
/*				/////////////////////////add at 20120527
				if(templeStateCnt==0&&cnt>0)
				{
					desc	=	"触发电话："+order_num+"没有有效的短信模板";
					retBo	=	TableCacheServer.genFailerMsg(desc);
					return retBo;
				}
				////////////////////////
*/				if(groupWhiteCnt==cnt)
				{
					desc ="主叫电话:"+mobile_num+";    为触发电话："+order_num+"的集团白名单，不需发送短信。";
					retBo	=	TableCacheServer.genFailerMsg(desc);
/*					retBo.setString("desc", desc);//
					retBo.setValue(RESULT,new ArrayList<BusiObj>());*/
					//vLogger.info( BOHelper.boToXML(retBo));
					return retBo;
				}
				if(whiteCnt==cnt)
				{
					desc ="主叫电话:"+mobile_num+";    为触发电话："+order_num+"的白名单，不需发送短信。";
					retBo	=	TableCacheServer.genFailerMsg(desc);
/*					retBo.setString("desc", desc);//
					retBo.setValue(RESULT,new ArrayList<BusiObj>());*/
					//vLogger.info( BOHelper.boToXML(retBo));
					return retBo;
				}
				if(groupCnt==0)
				{
					desc ="触发电话："+order_num+"没有配置短信模板发送群组。";
					retBo	=	TableCacheServer.genFailerMsg(desc);
/*					retBo.setString("desc",desc );//
					retBo.setValue(RESULT,new ArrayList<BusiObj>());*/
					//vLogger.info( BOHelper.boToXML(retBo));
					return retBo;
				}

			}
			vLogger.info("查询触发电话："+order_num+" 主叫号码："+mobile_num+" 通话状态："+cdr_type+"("+cdr_type_name+")"+"：" );
			return retBo;
		}
		catch(Throwable e)
		{
			vLogger.debug(LogCollect.getStackLog(e));//add at 20120524
			e.printStackTrace();
			desc		="查询触发电话："+order_num+" 主叫号码："+mobile_num+" 通话状态："+cdr_type+"("+cdr_type_name+")"+"的短信模板出现错误："+e.getMessage();
			retBo.setString("desc",desc );//
			retBo.setValue(RESULT,new ArrayList<BusiObj>());
			return retBo;
		}
		
	}
	private static boolean  isWhiteList(String ent_code,String mobile_num) throws BaseException
	{
		boolean	whiteListFlag	=	false;
		HashMap<String,String>	hWhiteList= null;hWhiteList=vWhiteListData.get(ent_code);//加载企业的白名单缓存
		boolean	whiteFlag=false;//白名单标志 
		vLogger.info("(2)===============判断主叫号码"+mobile_num+"是否为企业"+ent_code+"白名单：");
		if(!(hWhiteList==null||hWhiteList.size()==0))//主叫存在白名单
		{
			String	isWhiteList	=	hWhiteList.get(mobile_num);
			if(isWhiteList!=null &&(isWhiteList.trim().equals("1")))
				//vLogger.info("(2)===============主叫号码"+mobile_num+"为企业"+ent_code+"白名单：");
			{
				
				//hWhiteMobileNum.put(mobile_num, "0");//设置白名单手机号码
				//whiteCnt++;//白名单总数,每个模板都会校验主叫是否为白名单，如果该触发电话有多个模板，而主叫为该企业的白名单，则白名单总数=模板总数，如果该触发电话属于多个企业，则会取出另一企业的模板
				whiteListFlag	=	true;//设置白名单标志，只要这个电话是企业白名单，就跳过，白名单与模板无关
				vLogger.info("(2.0.99)===============主叫号码"+mobile_num+"为企业"+ent_code+"白名单：");

			}

		}
		return whiteListFlag;
	}
	public static String getCdrTypeName(String cdr_type)
	{
		String cdr_type_name="";
		if(cdr_type==null || cdr_type.trim().equals(""))
			cdr_type_name="未定义的cdr_type";
		if(cdr_type.equals("1"))
			cdr_type_name="通话";
		else if(cdr_type.equals("2"))
			cdr_type_name="占线";
		else if(cdr_type.equals("3"))
			cdr_type_name="无应答";
		else
			cdr_type_name="";
		return cdr_type_name;

	}
/*	public static void refresh (BusiObj bo) throws BaseException
	{
		Connection conn		=	bo.getConnection();
		if(!TableCacheServer.checkIsInit())//未初始化
		{
			TableCacheServer.init(conn);
			return;
		}
		TableCacheServer.refreshCallNumber(bo);
		TableCacheServer.refreshTriggerPhone(bo);
	}*/
	public static void refreshTriggerPhone (BusiObj bo) throws BaseException
	{
		Connection conn		=	bo.getConnection();
		////////////////////add at 20120523 插入刷新日志
/*		BusiObj	logBO		=	new BusiObj();
		logBO.setConnection(conn);
		logBO.setString("ent_code", bo.getString("ent_code"));*/
		////////////////////
		if(!TableCacheServer.checkIsInit())//未初始化
		{
			TableCacheServer.init(conn);
			return;
		}
		//String order_num		=	bo.getString("order_num");
		String ent_code				=	bo.getString("ent_code");
		String condition			=	" and a.ent_code=  "+ent_code+"  ";//	" and b.area_no||b.phone_num=  "+order_num+"  "
		String sql					=	TableCacheServer.genSqlTriggerPhone(condition);
		SQLArgs 	Arg				= 	new SQLArgs();
		Arg.reset();
		vLogger.info("refresh cache query smsTemple by triggerPhone  sql:" +sql);
		BusiObj		smsTempleBo 	= OperAgent.execQuery(conn, "query smsTemple by triggerPhone", sql, Arg);
		vLogger.info("返回数据是 refresh cache(1)query query smsTemple by triggerPhone: " + BOHelper.boToXML(smsTempleBo));
		
		//处理短信模板，key=被叫号码，即触发电话
		ArrayList<BusiObj> alSms		=	smsTempleBo.getBusiObjList(RESULT);
		HashMap<String,String> hRemove	=	new HashMap<String,String>();
		ArrayList<BusiObj> AlBo			=	null;
		//add at 20120405 考虑模版停用情况
		//先删除模版和群组缓存
		TableCacheServer.removeCacheTempleAndGroupByEndcode(ent_code, conn, Arg);
		if(alSms==null)
		{
			return;
		}
		for(BusiObj m:alSms)
		{
			String order_num 			= 	m.getString("order_num");
			if(vData.get(order_num)!=null&&(hRemove.get(order_num)==null))
			{
				vData.remove(order_num);
				AlBo					=	new	ArrayList<BusiObj>();
				hRemove.put(order_num, "0");//means this trigger phone has removes
			}
			else if(vData.get(order_num)==null)
			{
				AlBo					=	new	ArrayList<BusiObj>();
				hRemove.put(order_num, "0");//means this trigger phone has removes,so the trigger phone cannot be removed
			}
			else
			{
				AlBo					=	vData.get(order_num);
			}
			AlBo.add(m);
			vData.put(order_num, AlBo);
			String	desc	=	"(1)===============刷新触发电话"+order_num+"的模板信息："+ BOHelper.boToXML(m);
			vLogger.info(desc);
			///////////////////add at 20120523 插入刷新日志信息
			
/*			logBO.setString("refresh_desc", desc);
			TableCacheServer.logRefreshCallNumber(logBO);*/
		}

/*		ArrayList<BusiObj> arData = OperAgent.execQuery("根据号码获取数据");
		vData.put(num,arData);*/
	}
	////////////////////add at 20120429
	private static void refreshEntGroup(BusiObj bo) throws BaseException
	{
		String ent_code						=	bo.getString("ent_code");
		String sql 							=	" select a.ent_code,a.state,a.sub_state,a.flag, " +
												" a.ent_group_id,a.pre_ent_group_id " +
												" from enterprise a where ent_code=:ent_code ";//
		SQLArgs 	Arg						= 	new SQLArgs();
		Connection conn						=	bo.getConnection();
		vLogger.info("refresh cache  query enterprise's ent_group  sql:" +sql);
		Arg.reset();
		Arg.setArg("ent_code", ent_code);

		BusiObj		entBo 					= OperAgent.execQuery(conn, "enterprise's ent_group", sql, Arg);
		vLogger.info("返回数据是 refresh cache(ent_group)query enterprise's ent_group : " + BOHelper.boToXML(entBo));
		ArrayList<BusiObj> alEntBo			=	entBo.getBusiObjList(RESULT);
		for(BusiObj m:alEntBo)
		{
			String	ent_group_id			=	m.getString("ent_group_id");
			String	pre_ent_group_id		=	m.getString("pre_ent_group_id");
			BusiObj	entGroupBo				=	new	BusiObj();
			entGroupBo.setConnection(conn);
			entGroupBo.setString("ent_group_id", ent_group_id);
			TableCacheServer.refreshCacheEntGroup(entBo);
			entGroupBo.setString("ent_group_id", pre_ent_group_id);
			TableCacheServer.refreshCacheEntGroup(entBo);
		}
	}
	////////////////////add at 20120429
	private static void refreshCacheEntGroup(BusiObj bo) throws BaseException
	{
		String ent_group_id					=	bo.getString("ent_group_id","");
		if(CmPublic.isStrNullOrEmpty(ent_group_id))
			return ;
		HashMap<String,String>	hGroupEnt	=	TableCacheServer.getEntGroupByGroupId(bo);
		vEnterpriseGroupData.remove(ent_group_id);
		if(!(hGroupEnt==null||hGroupEnt.isEmpty()))
			vEnterpriseGroupData.put(ent_group_id, hGroupEnt);
	}
	////////////////////add at 20120429
	private static HashMap<String,String> getEntGroupByGroupId(BusiObj bo) throws BaseException
	{
		String ent_group_id					=	bo.getString("ent_group_id","");
		HashMap<String,String>	hGroupEnt	=	null;
		if(CmPublic.isStrNullOrEmpty(ent_group_id))
			return hGroupEnt;
			//throw new BaseException("Cache_00001","获取集团企业信息失败:  集团编码为空");
		Connection conn						=	bo.getConnection();
		SQLArgs 	Arg						= 	new SQLArgs();
		String sql 							=	" select ent_code,group_admin_flag " +
												" from enterprise " +
												" where  ent_group_id =:ent_group_id";
		Arg.reset();
		Arg.setArg("ent_group_id", ent_group_id);
		BusiObj		groupEntBo 				= 	OperAgent.execQuery(conn, "enterprise's ent_group", sql, Arg);
		ArrayList<BusiObj> alGroupEnt		=	groupEntBo.getBusiObjList(RESULT);
		for(BusiObj m:alGroupEnt)
		{
			String	ent_code				=	m.getString("ent_code");
			String	group_admin_flag		=	m.getString("group_admin_flag");
			hGroupEnt.put(ent_code, group_admin_flag);
		}
		return	hGroupEnt;
	}
	private static void logRefreshCallNumber (BusiObj bo) throws BaseException
	{
		String	ent_code		=	bo.getString("ent_code","-1");
		String	refresh_desc	=	bo.getString("refresh_desc","refresh_desc");
		
		if(refresh_desc.length()>3800)
			refresh_desc		=	refresh_desc.substring(0, 3800);
		Connection	conn		=	bo.getConnection();
		String	sql				=	" insert into log_refresh_cache" +
									" (ent_code,log_time,refresh_desc)" +
									" values(:ent_code,sysdate,:refresh_desc)";	
		SQLArgs 	Arg			= 	new SQLArgs();
		Arg.reset();
		Arg.setArg("refresh_desc", refresh_desc);
		Arg.setArg("ent_code", ent_code);
		OperAgent.execUpdate(conn, "logRefreshCallNumber ",sql, Arg);
		try {
			conn.commit();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			vLogger.debug(LogCollect.getStackLog(e));//add at 20120524
			e.printStackTrace();
			vLogger.info( "插入刷新缓存日志信息失败,企业编码:"+ent_code+"，入参包为:  "+ BOHelper.boToXML(bo)+"");
		}
		vLogger.info( "插入刷新缓存日志信息完成,企业编码:"+ent_code+"，入参包为:  "+ BOHelper.boToXML(bo)+"");
	}
	public static void refreshCallNumber (BusiObj bo) throws BaseException
	{
		try
		{
			//20120405 还需考虑模版停用情况，这时候企业是有效的。
			String ent_code						=	bo.getString("ent_code");
			vLogger.info( "刷新缓存,企业编码:"+ent_code+"，入参包为:  "+ BOHelper.boToXML(bo)+"" +
								"==========refresh cache start===============");
			Connection conn						=	bo.getConnection();
			//add at 20120523 只有master才能刷新
/*			BusiObj	logBO						=	new BusiObj();
			logBO.setConnection(conn);
			logBO.setString("ent_code", ent_code);*/
			if(vMode == 2 && vMaster.equals("1") == false)
			{
				String	desc					=	"===============Redis mode :该服务器不是master，不能进行刷新操作。";
				vLogger.info(desc);		
/*				logBO.setString("refresh_desc", desc);
				TableCacheServer.logRefreshCallNumber(logBO);*/
				return;
			}
			//add at 20120523 插入刷新日志
/*			logBO.setString("refresh_desc", "开始刷新日志");
			TableCacheServer.logRefreshCallNumber(logBO);*/
			
			if(!TableCacheServer.checkIsInit())//未初始化
			{
				TableCacheServer.init(conn);
				return;
			}
			if(!TableCacheServer.checkEntValid(bo))//无有效企业，则删除缓存
			{
				TableCacheServer.removeCacheByEntcode(bo);
				////////////////////add at 20120429
				TableCacheServer.refreshEntGroup(bo);
				return;
			}

			///////////因调用关系，共用一个接口，先刷触发电话
			TableCacheServer.refreshTriggerPhone(bo);
			////////////////////add at 20120429
			TableCacheServer.refreshEntGroup(bo);
			////////////////////
			String condition					=	" and a.ent_code=  "+ent_code+"  ";
	
			SQLArgs 	Arg						= 	new SQLArgs();
			//	 	GROUP_TYPE： 0：默认；1，客户群组；2：企业白名单
			Arg.reset();
			String	sql							=	TableCacheServer.genTempleGroup(condition);
			vLogger.info("refresh cache  query smsTempleGroup  sql:" +sql);
			BusiObj		templeGroupBo 			= OperAgent.execQuery(conn, "smsTempleGroup", sql, Arg);
			vLogger.info("返回数据是 refresh cache(2)query smsTempleGroup : " + BOHelper.boToXML(templeGroupBo));
			/////////////////add at 20121021 修正刷新时，会追加查到的记录而没有删除缓存中已有的记录，导致刷新一次就增加重复记录以及其余非预期结果
			//ArrayList<BusiObj>	AlNewRecordBo						=	new	ArrayList<BusiObj>();
			//
			HashMap<String,ArrayList<BusiObj>>	halNewTempleGroup	=	new	HashMap<String,ArrayList<BusiObj>>	();
			////////////////
			//处理模板群组,key=sms_temple_id
			ArrayList<BusiObj> alTempleGroup	=	templeGroupBo.getBusiObjList(RESULT);
			String group_type ="",group_id="",sms_temple_id="",mobile_num="";
			HashMap<String,String> h			=	new HashMap<String,String>();
			for(BusiObj m:alTempleGroup)
			{
				group_type						=	m.getString("group_type");
				group_id						=	m.getString("group_id");
				sms_temple_id					=	m.getString("sms_temple_id");
				mobile_num						=	m.getString("mobile_num");//A0,默认群组
				ent_code						=	m.getString("ent_code");
	
				ArrayList<BusiObj> AlBo			=	vTempleGroupData.get(sms_temple_id);
				if(AlBo==null)
				{
					AlBo						=	new	ArrayList<BusiObj>();
					h.put(sms_temple_id, "1");//表示缓存里面没有该模板，打入hash后，第二次进入的话，就不会删除缓存
				}
				else
				{
					String has_remove_temple	=	h.get(sms_temple_id);
					if(has_remove_temple==null||has_remove_temple.trim().equals(""))//只删除一次对应模板的缓存
					{
						h.put(sms_temple_id, "0");
						vTempleGroupData.remove(sms_temple_id);
					}
				}
				/////////////////add at 20121021 修正刷新时，会追加查到的记录而没有删除缓存中已有的记录，导致刷新一次就增加重复记录以及其余非预期结果
/*				AlBo.add(m);
				vTempleGroupData.put(sms_temple_id, AlBo);*/
				//20121207 一个用户多个模版导致模板群组有问题。容易找不着模板群组
				ArrayList<BusiObj>	AlNewRecordBo	=	halNewTempleGroup.get(sms_temple_id);
				if(AlNewRecordBo==null)
				{
					AlNewRecordBo						=	new	ArrayList<BusiObj>();
				}
				AlNewRecordBo.add(m);//上次1021内容
				halNewTempleGroup.put(sms_temple_id, AlNewRecordBo);

				vLogger.info("(2)===============刷新模板"+sms_temple_id+"的群组信息："+ BOHelper.boToXML(m));
			}
			//20121207 一个用户多个模版导致模板群组有问题。容易找不着模板群组
			for(String s_temple:halNewTempleGroup.keySet())
			{
				vTempleGroupData.put(s_temple, halNewTempleGroup.get(s_temple));
			}
			//vTempleGroupData.put(sms_temple_id, AlNewRecordBo);
			/////////end 
			//处理白名单，key=手机号码，即主叫号码
			//白名单
			condition							=	" and a1.ent_code=  "+ent_code+"  ";
			sql									=	TableCacheServer.genSqlWhite(condition);
			Arg.reset();
			vLogger.info("refresh cache query WhiteList  sql:" +sql);
			BusiObj		whiteListBo 			= OperAgent.execQuery(conn, "refresh cache  query WhiteList", sql, Arg);
			vLogger.info("返回数据是 refresh cache  query WhiteList :" + BOHelper.boToXML(whiteListBo));
			ArrayList<BusiObj> alWhite			=	whiteListBo.getBusiObjList(RESULT);
			HashMap<String,String> hWhite		=	new HashMap<String,String>();
			int	iWhiteCnt	=	0;
			for(BusiObj m:alWhite)
			{
				mobile_num						=	m.getString("mobile_num");
				//ArrayList<BusiObj> AlBo			=	vWhiteListData.get(ent_code);
				HashMap<String,String> hWhiteList			=	vWhiteListData.get(ent_code);
				/////////////////add at 20121021 修正刷新时，会追加查到的记录而没有删除缓存中已有的记录，导致刷新一次就增加重复记录以及其余非预期结果
				HashMap<String,String> hWhiteListNewRecord			=	vWhiteListData.get(ent_code);
				if(hWhiteListNewRecord==null)
				{
					hWhiteListNewRecord=	new HashMap<String,String> ();
				}
				if(hWhiteList==null)
				{
					hWhiteList =	new HashMap<String,String> ();
					hWhite.put(ent_code, "1");//表示缓存里面没有企业客户，打入hash后，第二次进入的话，就不会删除缓存
				}
				else
				{
					String has_remove_white		=	hWhite.get(ent_code);
	
					if(has_remove_white==null||has_remove_white.trim().equals(""))//只删除一次对应企业的缓存
					{
						hWhite.put(ent_code, "0");
						vWhiteListData.remove(ent_code);
					}
				}
				/////////////////add at 20121021 修正刷新时，会追加查到的记录而没有删除缓存中已有的记录，导致刷新一次就增加重复记录以及其余非预期结果
/*				hWhiteList.put(mobile_num, "1");
				vWhiteListData.put(ent_code, hWhiteList);*/
				hWhiteListNewRecord.put(mobile_num, "1");
				vWhiteListData.put(ent_code, hWhiteListNewRecord);
/*				if(AlBo==null)
				{
					AlBo						=	new	ArrayList<BusiObj>();
					hWhite.put(ent_code, "1");//表示缓存里面没有企业客户，打入hash后，第二次进入的话，就不会删除缓存
				}
				else
				{
					String has_remove_white		=	hWhite.get(ent_code);
	
					if(has_remove_white==null||has_remove_white.trim().equals(""))//只删除一次对应企业的缓存
					{
						hWhite.put(ent_code, "0");
						vWhiteListData.remove(ent_code);
					}
				}
				AlBo.add(m);
				vWhiteListData.put(ent_code, AlBo);*/
				//vLogger.info("(2)===============刷新企业"+ent_code+"的白名单信息："+ BOHelper.boToXML(m));
				iWhiteCnt++;
			}
			vLogger.info("(2)===============刷新企业"+ent_code+"的白名单信息共："+ iWhiteCnt+"条。");
			////////////////////////////////////////add at 20120328
			//刷新企业信息缓存
			condition							=	" and a.ent_code=  "+ent_code+"  ";
			sql									=	TableCacheServer.genSqlEnterprise(condition);
			Arg.reset();
			vLogger.info("refresh cache query enterprise  sql:" +sql);
			BusiObj		enterpriseBo 			= 	OperAgent.execQuery(conn, "refresh cache  query enterprise", sql, Arg);
			vLogger.info("返回数据是 refresh cache  query enterprise :" + BOHelper.boToXML(enterpriseBo));
			ArrayList<BusiObj> alEnterprise		=	enterpriseBo.getBusiObjList(RESULT);
			HashMap<String,String> hEnterprise	=	new HashMap<String,String>();
			/////////////////add at 20121021 修正刷新时，会追加查到的记录而没有删除缓存中已有的记录，导致刷新一次就增加重复记录以及其余非预期结果
			//AlNewRecordBo.clear();
			///////////end
			HashMap<String,ArrayList<BusiObj>>	halNewEnterprise	=	new	HashMap<String,ArrayList<BusiObj>>	();
			for(BusiObj m:alEnterprise)
			{
				String entCode					=	m.getString("ent_code");
				ArrayList<BusiObj> AlBo			=	vEnterpriseData.get(entCode);
				if(AlBo==null)
				{
					AlBo						=	new	ArrayList<BusiObj>();
					hEnterprise.put(ent_code, "1");//表示缓存里面没有企业客户，打入hash后，第二次进入的话，就不会删除缓存
				}
				else
				{
					String has_remove_ent		=	hEnterprise.get(ent_code);
	
					if(has_remove_ent==null||has_remove_ent.trim().equals(""))//只删除一次对应企业的缓存
					{
						hEnterprise.put(ent_code, "0");
						vEnterpriseData.remove(ent_code);
					}
				}
				/////////////////add at 20121021 修正刷新时，会追加查到的记录而没有删除缓存中已有的记录，导致刷新一次就增加重复记录以及其余非预期结果
/*				AlBo.add(m);
				vEnterpriseData.put(ent_code, AlBo);*/
				//20121207 一个用户多个模版导致模板群组有问题。容易找不着模板群组
				ArrayList<BusiObj>	AlNewRecordBo=	halNewEnterprise.get(ent_code);
				if(AlNewRecordBo==null)
				{
					AlNewRecordBo	=	new ArrayList<BusiObj>();
				}
				AlNewRecordBo.add(m);
				halNewEnterprise.put(ent_code, AlNewRecordBo);

				vLogger.info("(3)===============刷新企业"+ent_code+"的企业信息："+ BOHelper.boToXML(m));
			}
			ArrayList<BusiObj>	AlNewRecordBo=halNewEnterprise.get(ent_code);
			if(AlNewRecordBo==null)
			{
				vLogger.info("(3.0.9)===============刷新企业"+ent_code+"的企业信息：没有找到企业信息");
			}
			else
				vEnterpriseData.put(ent_code, AlNewRecordBo);
			/////////end
			////////////////////////////////////////add at 20120328
			vLogger.info( "刷新缓存,企业编码:"+ent_code+"" +
			"==========refresh cache end===============");
		}
		catch (Throwable e)
		{
			LogCollect.getStackLog(e);
			//vLogger.info("==========refresh cache failed==============="+e.getStackTrace());
			e.printStackTrace();
			vLogger.info("刷新缓存失败，入参包为:"+ BOHelper.boToXML(bo));
			vLogger.info("==========refresh cache failed==============="+LogCollect.getStackLog(e));//add at 20120524
		}
		
		
/*		//处理短信模板，key=被叫号码，即触发电话
		ArrayList<BusiObj> alSms				=	smsTempleBo.getBusiObjList(RESULT);
		if(vData.get(order_num)!=null)
			vData.remove(order_num);
		ArrayList<BusiObj> AlBo			=	new	ArrayList<BusiObj>();
		for(BusiObj m:alSms)
		{
			order_num = m.getString("order_num");
			AlBo.add(m);
		}
		vData.put(order_num, AlBo);*/
/*		ArrayList<BusiObj> arData = OperAgent.execQuery("根据号码获取数据");
		vData.put(num,arData);*/
	}


	
	public static void main(String[] args)  {
		
		try{
			//ETLLoger.getInstance().printInfo("---------------InitSystem-------------");
			int i=0;
			System.out.println("vName"+vName);
			vLogger = Logger.getLogger(TableCacheServer.class);
			vLogger.debug(vName);
			vLogger.info("---------------InitSystem1-------------");
			

		}

		catch(Exception e)
		{
			vLogger.error(e.getCause());
			e.printStackTrace();
		}
		finally
		{
		/*	try{
				if(pst != null) pst.close();
				if(rs != null) rs.close();
			}*/
		}
			vLogger.info("---------------Game Over-------------");
	

		
	}
	

}
